﻿using Learun.Util;
using Learun.Util.SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;

namespace Learun.Application.WorkFlow
{
    /// <summary>
    /// 版 本 PIT-ADMS V7.0.3 敏捷开发框架
    /// Copyright (c) 2013-2018 Hexagon PPM
    /// 创建人：研发部
    /// 日 期：2018.12.09
    /// 描 述：流程任务
    /// </summary>
    public class NWFTaskSerivce
    {
        #region 仓储
        Repository<NWFTaskEntity> _NWFTaskRepository => new Repository<NWFTaskEntity>();
        Repository<NWFTaskLogEntity> _NWFTaskLogRepository => new Repository<NWFTaskLogEntity>();
        Repository<NWFTaskRelationEntity> _NWFTaskRelationRepository => new Repository<NWFTaskRelationEntity>();
        #endregion
        #region 获取数据
        /// <summary>
        /// 获取所有的任务
        /// </summary>
        /// <param name="processId">流程进程主键</param>
        /// <returns></returns>
        public IEnumerable<NWFTaskEntity> GetALLTaskList(string processId)
        {
            try
            {
                //return this.BaseRepository().FindList<NWFTaskEntity>(t => t.F_ProcessId == processId);
                return _NWFTaskRepository.GetList(t => t.F_ProcessId == processId);
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        /// <summary>
        /// 获取未完成的任务
        /// </summary>
        /// <param name="processId">流程进程主键</param>
        /// <returns></returns>
        public IEnumerable<NWFTaskEntity> GetUnFinishTaskList(string processId) {

            try
            {
                return _NWFTaskRepository.GetList(t=>t.F_ProcessId == processId && t.F_IsFinished == 0);
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        /// <summary>
        /// 获取所有未完成的任务
        /// </summary>
        /// <returns></returns>
        public IEnumerable<NWFTaskEntity> GetUnFinishTaskList()
        {
            try
            {
                return _NWFTaskRepository.GetList(t => t.F_IsFinished == 0 && (t.F_Type == 1 || t.F_Type == 3));
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }

        /// <summary>
        /// 判断任务是否允许撤销
        /// </summary>
        /// <param name="processId">流程实例</param>
        /// <param name="preNodeId">上一个节点（撤销任务节点）</param>
        /// <returns></returns>
        public bool IsRevokeTask(string processId,string preNodeId)
        {
            try
            {
                bool res = true;
                var list = _NWFTaskRepository.GetList(t=> t.F_ProcessId == processId && t.F_PrevNodeId == preNodeId && t.F_Type == 1 && t.F_IsFinished == 1);
                var list2 = _NWFTaskRepository.GetList(t => t.F_ProcessId == processId && t.F_PrevNodeId == preNodeId && (t.F_Type == 1 || t.F_Type == 5) && t.F_IsFinished == 0);
                if (list2.Count > 0)
                {
                    return res;
                }
                foreach (var item in list) {
                    string nodeId = item.F_NodeId;
                    var entity = _NWFTaskRepository.GetFirst(t => t.F_ProcessId == processId && t.F_NodeId == nodeId && t.F_IsFinished == 0);

                    if (entity == null) {
                        res = false;
                        break;
                    }
                }

                return res;
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }

        /// <summary>
        /// 获取流程任务实体
        /// </summary>
        /// <param name="keyValue">主键</param>
        /// <returns></returns>
        public NWFTaskEntity GetEntity(string keyValue)
        {
            try
            {
                return _NWFTaskRepository.GetById(keyValue);
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        /// <summary>
        /// 获取最近一次的任务信息（审批任务）
        /// </summary>
        /// <param name="nodeId">节点Id</param>
        /// <param name="processId">流程进程主键</param>
        /// <returns></returns>
        public NWFTaskEntity GetEntityByNodeId(string nodeId, string processId) {
            try
            {
                var strSql = new StringBuilder();
                strSql.Append(@"SELECT * FROM LR_NWF_Task WHERE F_ProcessId = @processId AND F_NodeId = @nodeId AND F_Type != 3 ORDER BY F_CreateDate DESC");
                return SqlSugarHelper.Db.Ado.SqlQuerySingle<NWFTaskEntity>(strSql.ToString(), new { processId, nodeId });
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        /// <summary>
        /// 获取任务执行人列表
        /// </summary>
        /// <param name="taskId">任务主键</param>
        /// <returns></returns>
        public IEnumerable<NWFTaskRelationEntity> GetTaskUserList(string taskId) {
            try
            {
                var strSql = new StringBuilder();
                strSql.Append(@"SELECT t1.*,t2.F_RealName FROM LR_NWF_TaskRelation t1 LEFT JOIN lr_base_user t2 ON t1.F_UserId = t2.F_UserId WHERE t1.F_TaskId = @taskId  ORDER BY t1.F_Sort");
                return SqlSugarHelper.Db.SqlQueryable<NWFTaskRelationEntity>(strSql.ToString()).AddParameters(new { taskId }).ToList();
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        /// <summary>
        /// 获取任务执行日志实体
        /// </summary>
        /// <param name="nodeId">节点Id</param>
        /// <param name="prcoessId">流程进程主键</param>
        /// <returns></returns>
        public IEnumerable<NWFTaskLogEntity> GetLogEntityByNodeId(string nodeId,string prcoessId) {
            try
            {
                return _NWFTaskLogRepository.GetList(t=>t.F_NodeId.Equals(nodeId)&&t.F_ProcessId.Equals(prcoessId) && t.F_TaskType != 3&& t.F_TaskType != 6);
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        /// <summary>
        /// 获取任务执行日志列表
        /// </summary>
        /// <param name="nodeId">节点Id</param>
        /// <param name="prcoessId">流程进程主键</param>
        /// <returns></returns>
        public IEnumerable<NWFTaskLogEntity> GetLogListByNodeId(string nodeId, string prcoessId)
        {
            try
            {
                return _NWFTaskLogRepository.GetList(t => t.F_NodeId.Equals(nodeId) && t.F_ProcessId.Equals(prcoessId) && t.F_TaskType == 1);
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        /// <summary>
        /// 获取流程进程的任务处理日志
        /// </summary>
        /// <param name="prcoessId">流程进程主键</param>
        /// <returns></returns>
        public IEnumerable<NWFTaskLogEntity> GetLogList(string processId)
        {
            try
            {
                var strSql = new StringBuilder();
                strSql.Append(@"SELECT * FROM LR_NWF_TaskLog WHERE F_ProcessId = @processId ORDER BY F_CreateDate DESC ");

                //return this.BaseRepository().FindList<NWFTaskLogEntity>(strSql.ToString(),new { processId });
                return SqlSugarHelper.Db.SqlQueryable<NWFTaskLogEntity>(strSql.ToString()).AddParameters(new { processId }).ToList();
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        /// <summary>
        ///  获取流程进程的任务处理日志列表
        /// </summary>
        /// <param name="pagination">分页参数</param>
        /// <param name="processId">流程进程主键</param>
        /// <returns></returns>
        public IEnumerable<NWFTaskLogEntity> GetTaskLogPageList(Pagination pagination, string processId, int type)
        {
            try
            {
                var strSql = new StringBuilder();
                if (type == 2)
                {
                    strSql.Append(@"SELECT a.*,c.RoleUserList  FROM LR_NWF_TaskLog a LEFT JOIN ZSJT_BIMCD_CapitalRaising c ON a.F_ProcessId=c.ProcessId  WHERE a.F_ProcessId = @processId   AND  a.F_TaskId IS NOT NULL AND a.F_OperationCode<>'revokeAudit'  ");
                }
                else
                {
                    strSql.Append(@"SELECT a.*   FROM LR_NWF_TaskLog a  WHERE a.F_ProcessId = @processId   AND  a.F_TaskId IS NOT NULL AND a.F_OperationCode<>'revokeAudit'  ");
                }
                //return this.BaseRepository().FindList<NWFTaskLogEntity>(strSql.ToString(), new { processId },pagination);
                return SqlSugarHelper.Db.SqlQueryable<NWFTaskLogEntity>(strSql.ToString()).AddParameters(new { processId }).ToPageList(pagination.page, pagination.rows);
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }


        /// <summary>
        /// 获取流程每个节点最新的任务处理列表
        /// </summary>
        /// <param name="pagination">分页参数</param>
        /// <param name="prcoessId">流程进程主键</param>
        /// <returns></returns>
        public IEnumerable<NWFTaskLogEntity> GetEachNodeLogPageList(Pagination pagination, string processId, int type)
        {
            try
            {
                var strSql = new StringBuilder();
                if (type == 2)
                {
                    strSql.Append(@" select a.*,c.RoleUserList  FROM LR_NWF_TaskLog a LEFT JOIN ZSJT_BIMCD_CapitalRaising c ON a.F_ProcessId=c.ProcessId   WHERE not exists(select 1  
                      from LR_NWF_TaskLog b  
                       where  b.F_NodeId=a.F_NodeId AND b.F_CreateUserId=a.F_CreateUserId AND b.F_CreateDate>a.F_CreateDate) AND  a.F_ProcessId=@processId   AND  a.F_TaskId IS NOT NULL AND a.F_OperationCode<>'revokeAudit'  ");
                } else {
                    strSql.Append(@" select a.*  FROM LR_NWF_TaskLog a   WHERE not exists(select 1  
                      from LR_NWF_TaskLog b  
                       where  b.F_NodeId=a.F_NodeId AND b.F_CreateUserId=a.F_CreateUserId AND b.F_CreateDate>a.F_CreateDate) AND  a.F_ProcessId=@processId AND  a.F_TaskId IS NOT NULL AND a.F_OperationCode<>'revokeAudit'  ");
                }
                return SqlSugarHelper.Db.SqlQueryable<NWFTaskLogEntity>(strSql.ToString()).AddParameters(new { processId }).ToPageList(pagination.page, pagination.rows);
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        /// <summary>
        /// 获取流程每个节点最新的任务处理记录
        /// </summary>
        /// <param name="prcoessId">流程进程主键</param>
        /// <returns></returns>
        public IEnumerable<NWFTaskLogEntity> GetEachNodeLogList(string processId)
        {
            try
            {
                var strSql = new StringBuilder();
                strSql.Append(@"  select a.*  FROM LR_NWF_TaskLog a  WHERE not exists(select 1  
                      from LR_NWF_TaskLog b  
                       where b.F_NodeId=a.F_NodeId  AND b.F_CreateUserId=a.F_CreateUserId  AND b.F_CreateDate>a.F_CreateDate) AND  F_ProcessId=@processId   ORDER BY a.F_CreateDate  ");
                //return this.BaseRepository().FindList<NWFTaskLogEntity>(strSql.ToString(), new { processId });
                return SqlSugarHelper.Db.SqlQueryable<NWFTaskLogEntity>(strSql.ToString()).AddParameters(new { processId }).ToList();
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        /// <summary>
        /// 获取流程进程的任务处理日志
        /// </summary>
        /// <param name="taskId">任务主键</param>
        /// <param name="userId">用户主键</param>
        /// <returns></returns>
        public NWFTaskLogEntity GetLogEntity(string taskId,string userId)
        {
            try
            {
                return _NWFTaskLogRepository.GetFirst(t=>t.F_TaskId == taskId && t.F_CreateUserId == userId && t.F_TaskType != 100);
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }

        /// <summary>
        /// 获取当前任务节点ID
        /// </summary>
        /// <param name="processId">流程进程主键</param>
        /// <returns></returns>
        public List<string> GetCurrentNodeIds(string processId)
        {
            try
            {
                var strSql = new StringBuilder();
                strSql.Append(@"SELECT
	                                t.F_NodeId
                                FROM
	                                LR_NWF_Task t
                                WHERE
	                                t.F_IsFinished = 0 AND t.F_ProcessId = @processId
                                GROUP BY
	                                t.F_NodeId      
                ");
                //var taskList = this.BaseRepository().FindList<NWFTaskEntity>(strSql.ToString(), new { processId });
                var taskList = SqlSugarHelper.Db.SqlQueryable<NWFTaskEntity>(strSql.ToString()).AddParameters(new { processId }).ToList();
                List<string> list = new List<string>();
                foreach (var item in taskList)
                {
                    list.Add(item.F_NodeId);
                }
                return list;
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        #endregion

        #region 保存数据
        /// <summary>
        /// 更新审核人
        /// </summary>
        /// <param name="list">审核人列表</param>
        /// <param name="taskList">任务列表</param>
        /// <param name="nWFTaskLogEntity">任务日志</param>
        public void Save(List<NWFTaskRelationEntity> list, List<string> taskList, NWFTaskLogEntity nWFTaskLogEntity)
        {
            SqlSugarHelper.Db.BeginTran();
            try
            {
                foreach (string taskId in taskList) {
                    _NWFTaskRelationRepository.Delete(t => t.F_TaskId == taskId && t.F_Result == 0 && t.F_Mark == 0);
                }

                foreach (var taskUser in list) {
                    _NWFTaskRelationRepository.Insert(taskUser);
                }

                _NWFTaskLogRepository.Insert(nWFTaskLogEntity);

                SqlSugarHelper.Db.CommitTran();
            }
            catch (Exception ex)
            {
                SqlSugarHelper.Db.RollbackTran();
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }

        /// <summary>
        /// 更新是否查看状态
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <param name="isLook">是否查看</param>
        /// <param name="UserId">用户ID</param>
        public void UpdateLook(string taskId, int isLook, string UserId)
        {
            try
            {
                SqlSugarHelper.Db.BeginTran();
                NWFTaskRelationEntity entity = _NWFTaskRelationRepository.GetFirst(o => o.F_TaskId == taskId && o.F_UserId == UserId);
                if (entity != null)
                {
                    entity.IsLook = isLook;
                    _NWFTaskRelationRepository.Update(entity);
                }
                SqlSugarHelper.Db.CommitTran();
            }
            catch (Exception ex)
            {
                SqlSugarHelper.Db.RollbackTran();
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        #endregion
    }
}
